"""
@author: Leo
@version: 1.0.0
@file: wechat_qr_view.py
@time: 2023/9/17 10:47 AM
"""
import copy
from datetime import timedelta

from django.contrib.auth.models import User
from django.core.cache import cache
from django.db import transaction
from django.utils.timezone import now

from lab.common.base_model_view_set import BaseModelViewSet
from lab.common.enums import ErrorCodeEnum
from lab.common.id_factory import id_factory
from lab.common.response import BadRequest, OK
from lab.user.auth.serializers import WechatQrScanSerializer, \
    WechatQrScanWithPhonenumberAndVerificationCodeSerializer
from lab.user.models import ExtendedUser
from lab.utils.jwt_utils import JwtUtils
from lab.utils.wechat_utils import WechatUtilsWrapper


class WechatQrScanLoginViewSet(BaseModelViewSet):
    """
    create:
        微信扫码登录
    """
    serializer_class = WechatQrScanSerializer

    def create(self, request):
        open_id_code = request.data.get('open_id_code')
        union_id = WechatUtilsWrapper.get_union_id_via_qr_scan(open_id_code)
        extended_user = ExtendedUser.objects.filter(union_id=union_id).first()
        if not extended_user:
            err_dict = copy.deepcopy(ErrorCodeEnum.PHONE_NUMBER_REQUIRED.value)
            err_dict.update({'data': {'union_id': union_id}})
            raise BadRequest(err_dict)
        else:
            return OK({
                'user_id': extended_user.id,  # this is the extended user
                'user_name': extended_user.user.username,
                'token': JwtUtils.generate_jwt_token(extended_user.id, extended_user.user.username),
                'refresh_token': JwtUtils.generate_jwt_refresh_token(extended_user.id, extended_user.user.username)
            })


class WechatQrScanLoginWithPhoneNumberViewSet(BaseModelViewSet):
    """
    create:
        微信扫码登录，绑定手机号码
    """
    serializer_class = WechatQrScanWithPhonenumberAndVerificationCodeSerializer

    def create(self, request):
        union_id = request.data.get('union_id')
        phone_number = request.data.get('phone_number')
        verification_code = request.data.get('verification_code')

        if cache.get(phone_number) != verification_code:
            raise BadRequest(ErrorCodeEnum.INVALID_VERIFICATION_CODE.value)

        extended_user = ExtendedUser.objects.filter(phone_number=phone_number).first()
        if extended_user and extended_user.union_id is not None:
            raise BadRequest(ErrorCodeEnum.PHONE_NUMBER_ALREADY_BOUND.value)

        if extended_user and extended_user.union_id is None:
            extended_user.union_id = union_id
            extended_user.save()
        elif not extended_user:
            with transaction.atomic():
                user = User.objects.create(email=f'{phone_number}@anying.com',
                                           username=f'微信用户-{id_factory.get_unique_id()}')
                extended_user = ExtendedUser.objects.create(phone_number=phone_number, user_id=user.id,
                                                            union_id=union_id, vip_expired_time=now()+timedelta(days=14))
        return OK({
            'user_id': extended_user.id,  # this is the extended user
            'user_name': extended_user.user.username,
            'token': JwtUtils.generate_jwt_token(extended_user.id, extended_user.user.username),
            'refresh_token': JwtUtils.generate_jwt_refresh_token(extended_user.id, extended_user.user.username)
        })
